#include "Texture.h"
#include <glad/glad.h>
#include <GLFW/glfw3.h>

namespace OCPP
{
	Texture::Texture(const String fileName, GLenum texType, String textureType)
	{
		Image image;
		image.load(fileName, "");
		image.flipAroundX();
		init(image, texType, textureType);
	}

	Texture::~Texture()
	{
		glDeleteTextures(1, &ID);
	}

	void Texture::init(Image& image, GLenum texType, String textureType)
	{
		mType = texType;
		mTextureType = textureType;

		// Generates an OpenGL texture object
		glGenTextures(1, &ID);

		glBindTexture(texType, ID);

		// Configures the type of algorithm that is used to make the image smaller or bigger
		glTexParameteri(texType, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);
		glTexParameteri(texType, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

		// Configures the way the texture repeats (if it does at all)
		glTexParameteri(texType, GL_TEXTURE_WRAP_S, GL_REPEAT);
		glTexParameteri(texType, GL_TEXTURE_WRAP_T, GL_REPEAT);

		PixelFormat pf = image.getFormat();
		GLenum format = getGLOriginFormat(pf);
		GLenum pixelType = getGLOriginDataType(pf);
		GLenum internalFormat = getGLInternalFormat(pf, false);
		
		// Assigns the image to the OpenGL Texture object
		glTexImage2D(texType, 0, internalFormat, image.getWidth(), image.getHeight(), 0, format, pixelType, image.getData());
		// Generates MipMaps
		glGenerateMipmap(texType);

		// Unbinds the OpenGL Texture object so that it can't accidentally be modified
		glBindTexture(texType, 0);
	}

	void Texture::bind(int unit)
	{
		glActiveTexture(GL_TEXTURE0 + unit);
		glBindTexture(mType, ID);
	}

	void Texture::unbind()
	{
		glBindTexture(mType, 0);
	}
}